package com.ls.nio;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 一、通道（Channel）:用于源节点和目标节点的连接。在Java nio中负责缓冲区中数据的传输。
 *      Channel本身不存储数据，因此需要配合缓冲区进行传输。
 *
 *      二、通道的主要实现类
 *      java.nio.channels.Channel 接口
 *              |--FileChannel
 *              |--SocketChannel
 *              |--ServerSocketChannel
 *              |--DatagramChannel
 *      三、获取通道
 *      1.Java针对支持通道的类提供了getChannel()方法
 *           本地IO:
 *               FileInputStream、FileOutputStream
 *               RandomAccessFile
 *           网络IO:
 *               Socket
 *               ServerSocket
 *               DatagramSocket
 *      2、在JDK1.7中的NIO.2针对各个通道提供了静态方法open()
 *      3、在JDK1.7中的NIO.2的File工具类的newByteChannel()
 */
public class TestChannel {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel inChannel = null;
        FileChannel outChannel = null;

        try {
            fis = new FileInputStream("/Users/liushuai/Desktop/1.jpg");
            fos = new FileOutputStream("/Users/liushuai/Desktop/2.jpg");
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();

            ByteBuffer buf = ByteBuffer.allocate(1024);

            while (inChannel.read(buf) != -1){
                buf.flip();
                outChannel.write(buf);
                buf.clear();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if ( outChannel != null) {
                try {
                    outChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inChannel!=null) {
                try {
                    inChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis!=null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 通道内直接传
     */
    @Test
    public void test02() throws IOException {
        FileChannel inChannel = FileChannel.open(Paths.get("/Users/liushuai/Desktop/1.jpg"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("/Users/liushuai/Desktop/2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);

        inChannel.transferTo(0, inChannel.size(), outChannel);
        //outChannel.transferFrom(inChannel,0,inChannel.size());
        inChannel.close();
        outChannel.close();

    }}
